# _*_ coding:utf-8 _*_
# @author : Joyamon
# @time : 2022-12-12 13:57
# @file : Captcha.py

import random
import string
from PIL import Image, ImageDraw, ImageFont
import os


# Image :一个画布
# ImageDraw:一个画笔
# ImageFont:画笔的字体


class Captcha(object):
    number = 4
    size = (100, 30)
    fontsize = 25
    line_number = 2

    # 构建一个验证码源文本(字母和数字)
    SOURCE = list(string.ascii_letters + os.path.join(string.digits))

    @classmethod
    def __gene_line(cls, draw, width, height):
        """
        绘制干扰线
        """
        begin = (random.randint(0, width), random.randint(0, height))
        end = (random.randint(0, width), random.randint(0, height))
        draw.line([begin, end], fill=cls.__gene_random_color())

    @classmethod
    def __gen_points(cls, draw, point_chance, width, height):
        """
        生成干扰点
        """
        chance = min(100, max(0, int(point_chance)))  # 大小限制在[0,100]
        for w in range(width):
            for h in range(height):
                tmp = random.randint(0, 100)
                if tmp > 100 - chance:
                    draw.point((w, h), fill=cls.__gene_random_color())

    @classmethod
    def __gene_random_color(cls, start=0, end=255):
        """
        生成随机颜色
        """
        random.seed()
        return (random.randint(start, end), random.randint(start, end),
                random.randint(start, end))

    @classmethod
    def __gene_random_font(cls):
        """
        随机选择一个字体
        """
        fonts = [
            'verdana.ttf'
        ]
        font = random.choice(fonts)
        return font

    @classmethod
    def __gene_text(cls, number):
        """
        随机生成一个字符串
        number是生成验证码的位数
        """
        return ''.join(random.sample(cls.SOURCE, number))

    @classmethod
    def gene_graph_captcha(cls):
        """
        生成验证码
        """
        width, height = cls.size
        image = Image.new('RGBA', (width, height), cls.__gene_random_color(0, 100))
        font = ImageFont.truetype(cls.__gene_random_font(), cls.fontsize)
        draw = ImageDraw.Draw(image)
        text = cls.__gene_text(cls.number)
        # 获取字体尺寸
        font_width, font_height = font.getsize(text)
        draw.text(((width - font_width) / 2, (height - font_height) / 2), text, font=font,
                  fill=cls.__gene_random_color(150, 255))
        # 绘制干扰线

        for x in range(0, cls.line_number):
            cls.__gene_line(draw, width, height)
        # 绘制干扰点
        cls.__gen_points(draw, 10, width, height)
        return text, image
